package com.feng.controller;

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import com.alibaba.fastjson2.JSONObject;
import com.feng.entity.User;
import com.feng.repository.ChatHistoryRepository;
import com.feng.utils.Const;
import com.feng.utils.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.Media;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.MimeType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Objects;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;

@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class SpringChatController {

    private final ChatClient chatClient;

    private final ChatHistoryRepository chatHistoryRepository;

    private final StringRedisTemplate redisTemplate;

    private final JwtUtil jwtUtil;



    @RequestMapping(value = "/chat", produces = "text/html;charset=UTF-8")
    public Flux<String> chat(@RequestParam("prompt") String prompt,
                             @RequestParam("chatId") String chatId,
                             @RequestParam(value = "files",required = false) List<MultipartFile> files,
                             HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            String id = jwtUtil.verifyToken(token);
            System.out.println("验证 Token 得到的用户 ID: " + id);
            if (id != null) {
                String redisKey = "login:" + id;
                System.out.println("尝试获取的 Redis 键名: " + redisKey);
                User user = JSONObject.parseObject(redisTemplate.opsForValue().get(redisKey), User.class);
                if (user != null) {
                    chatHistoryRepository.save(Const.CHAT, chatId, user.getAccount().getId());
                    if(files == null || files.isEmpty()){
                        return textChat(prompt, chatId);
                    }else {
                        return MultiModelChat(prompt,chatId, files);
                    }
                }
            }
        }
        return Flux.just("请您先登录");
    }

    private Flux<String> MultiModelChat(String prompt,String chatId, List<MultipartFile> files) {
        List<Media> medias = files.stream()
                .map(file -> new Media(MimeType.valueOf(Objects.requireNonNull(file.getContentType())),
                        file.getResource())).toList();

        return chatClient.prompt(new Prompt(
                        prompt,
                        DashScopeChatOptions.builder()
                                .withModel("qwen-omni-turbo")
                                .withMultiModel(true)
                                .withTemperature(0.8)
                                .build())
                )
                .user(p -> p.media(medias.toArray(Media[]::new)))
                .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId))
                .stream()
                .content()
                .onErrorResume(e -> Flux.just("服务暂时不可用，请稍后重试"));

    }

    private Flux<String> textChat(String prompt, String chatId) {
        return chatClient.prompt(new Prompt(
                prompt,
                DashScopeChatOptions.builder()
                        .withModel("qwen-omni-turbo")
                        .withMultiModel(true)
                        .withTemperature(0.8)
                        .build())
               )
               .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId))
               .stream()
               .content()
               .onErrorResume(e -> Flux.just("服务暂时不可用，请稍后重试"));
//       下面的ollama可以用
//        return chatClient
//                .prompt()
//                .user(prompt)
//                .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId))
//                .stream()
//                .content()
//                .onErrorResume(e -> Flux.just("服务暂时不可用，请稍后重试"));
    }
}
